/**
****************************************************************
* @file iso15693.c
*
* @brief  关于15693协议一些基本的底层驱动接口
*
* @author
*
*
****************************************************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "iso15693.h"
#include "rfid.h"
#include "sys_init.h"
#include "bit_define.h"

extern uint8_t NFC_DEBUG_LOG;

int pcd_send_eof(uint8_t *pRxBuffer, uint16_t *pRxLength)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t pi;

    if(NFC_DEBUG_LOG)
    {
        printf("SEND EOF:\n");
    }

    pcd_set_15693_tmo(4);

    hal_nfc_write_register(0x37, 0x55);
    hal_nfc_set_register_bit(0x31,BIT(4));
    hal_nfc_write_register(0x37, 0x00);

    hal_nfc_write_register(REG_COMMAND, PCD_TRANSMIT);
    hal_nfc_set_register_bit(REG_BITFRAMING,0x80);

    pi.mf_command = PCD_RECEIVE;
    status = pcd_com_transceive(&pi);

    hal_nfc_write_register(0x37, 0x55);
    hal_nfc_clear_register_bit(0x31,BIT(4));
    hal_nfc_write_register(0x37, 0x00);

    if (status != HAL_STATUS_OK)
    {
        return status;
    }

    *pRxLength = (pi.mf_length / 8);
    memcpy(pRxBuffer, pi.mf_data, *pRxLength);

    return HAL_STATUS_OK;
}

int pcd_inventory(
    uint8_t bFlag,
    uint8_t  bAfi,
    uint8_t *pMask,
    uint8_t  bMaskBitLength,
    TypeV_Info_t *pTypeV_Info_t
)
{
    int status = HAL_STATUS_TIMEOUT;
    uint8_t bNextSlot = 1;
    uint8_t bSlot = 0;
    uint8_t bSlotCount = 0;
    uint8_t bLevel = 0;
    uint8_t bEnd = 0;
    uint8_t bRepeat = 0;
    uint8_t bCount[16] = {0};
    uint16_t wCollisionLogReg[16] = {0};
    uint8_t aEofRecvTmpBuff[10];
    uint16_t bEofRecvTmpLen;
    // static uint8_t  bit_rand = 0;
    uint8_t  bit_index = 0;
    uint8_t  byte_index = 0;
    uint8_t  last_bit = 0;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("INVENTORY:\n");
    }

    pTypeV_Info_t->bCardNum = 0;
    pTypeV_Info_t->bCollPend = 0;
#if (USE_BIT_AND_SLOT_ANTI_COLLSION)
    do
    {
#endif
        pcd_set_15693_tmo(4);
        pi.mf_command = PCD_TRANSCEIVE;
        pi.mf_data[0] = bFlag; //Data_rate_flag | Inventory_flag | Nb_slots_flag;; //??:?????????flag[8:5] ???5( 1 slot )
        pi.mf_data[1] = INVENTORY_CMD;

        if((bFlag & INVENTORY_FLAG) && (bFlag & AFI_FLAG))      //AFI_Flag = 1
        {
            pi.mf_data[2] = bAfi;
            pi.mf_data[3] = bMaskBitLength;


            if(bMaskBitLength == 0)
            {
                pi.mf_length = 4;
            }
            else
            {
                memcpy(&pi.mf_data[4], pMask, (mask_byte_number(bMaskBitLength) + 1));
                pi.mf_length = 4 + mask_byte_number(bMaskBitLength) + 1;
            }
        }
        else
        {
            pi.mf_data[2] = bMaskBitLength;

            if(bMaskBitLength == 0)
            {
                pi.mf_length = 3;
            }
            else
            {
                memcpy(&pi.mf_data[3], pMask, (mask_byte_number(bMaskBitLength) + 1));
                pi.mf_length = 3 + mask_byte_number(bMaskBitLength) + 1;
            }
        }

        status = pcd_com_transceive(&pi);
        if(status == HAL_STATUS_TIMEOUT)
        {
            return status;
        }
        else
        {
            if(status == HAL_STATUS_OK)
            {
                pTypeV_Info_t->aTypeV[pTypeV_Info_t->bCardNum].bDsfid = pi.mf_data[1];
                memcpy(pTypeV_Info_t->aTypeV[pTypeV_Info_t->bCardNum].aUid, &pi.mf_data[2], ISO15693_UID_LENGTH);

                pTypeV_Info_t->bCardNum++;
                return HAL_STATUS_OK;
            }
            else if(status == HAL_STATUS_COLLERR)
            {
                pTypeV_Info_t->bCollPend = 1;
                pi.mf_data[0] = pi.mf_data[0] + 1;		//???????

#if (USE_BIT_AND_SLOT_ANTI_COLLSION)
                /* The location where the collision occurred is in the first 32 bits, The slot = 1 mechanism is used to prevent conflicts */
                if(pi.mf_data[0] <= 32)
                {
                    /* The first two bytes coll */
                    if(pi.mf_data[0] <= 0x10)
                    {
                        bMaskBitLength = 0;
                        break;
                    }
                    bit_rand += 1;
                    bMaskBitLength = pi.mf_data[0] - 16;       //???mask??,16?FLAG?DSFID??
                    bit_index = mask_bit_number(bMaskBitLength);        //???bit
                    byte_index = mask_byte_number(bMaskBitLength);      //??bit??pMask????
                    memcpy(pMask, &pi.mf_data[3], byte_index + 1);     //??????UID???? + 1

                    pMask[byte_index] = bit_index * bit_random(bit_rand);       //??bit????

                    for(bit_index = 0; bit_index <= ((bMaskBitLength - 1) % 8); bit_index++)
                    {
                        last_bit |= BIT(bit_index);
                    }

                    pMask[byte_index] |= (last_bit & pi.mf_data[3]);       //???????????????
                    continue;
                }
                /* Otherwise, use slot=16 to prevent conflicts */
                else
                {
                    bMaskBitLength = 16;      //?????????????bMaskBitLength
                    memcpy(pMask, &pi.mf_data[3], 2);      //??????UID????
#endif
                    bFlag = (bFlag & (~NB_SLOTS_FLAG));
                    do
                    {
                        pcd_set_15693_tmo(4);
                        pi.mf_command = PCD_TRANSCEIVE;
                        pi.mf_data[0] = bFlag;
                        pi.mf_data[1] = INVENTORY_CMD;

                        if((bFlag & INVENTORY_FLAG) && (bFlag & AFI_FLAG))      //AFI_Flag = 1
                        {
                            pi.mf_data[2] = bAfi;
                            pi.mf_data[3] = bMaskBitLength;

                            if(bMaskBitLength == 0)
                            {
                                pi.mf_length = 4;
                            }
                            else
                            {
                                memcpy(&pi.mf_data[4], pMask, (mask_byte_number(bMaskBitLength) + 1));
                                pi.mf_length = 4 + mask_byte_number(bMaskBitLength) + 1;
                            }
                        }
                        else
                        {
                            pi.mf_data[2] = bMaskBitLength;

                            if(bMaskBitLength == 0)
                            {
                                pi.mf_length = 3;
                            }
                            else
                            {
                                memcpy(&pi.mf_data[3], pMask, (mask_byte_number(bMaskBitLength) + 1));
                                pi.mf_length = 3 + mask_byte_number(bMaskBitLength) + 1;
                            }
                        }

                        status = pcd_com_transceive(&pi);

                        memcpy(aEofRecvTmpBuff, &pi.mf_data[0], 10);
                        bSlot = 0;

                        /* Loop till 16 slots or collision error */
                        do
                        {
                            if(status == HAL_STATUS_TIMEOUT)
                            {
                                /* Continue with next slot */
                            }
                            else if(status == HAL_STATUS_COLLERR)
                            {
                                pTypeV_Info_t->bCollPend = 1;
                                wCollisionLogReg[bLevel] |= ((uint16_t)1U)<< bSlot;
                            }
                            else if(status == HAL_STATUS_OK)
                            {
                                pTypeV_Info_t->aTypeV[pTypeV_Info_t->bCardNum].bDsfid = aEofRecvTmpBuff[1];
                                memcpy(pTypeV_Info_t->aTypeV[pTypeV_Info_t->bCardNum].aUid, &aEofRecvTmpBuff[2], ISO15693_UID_LENGTH);

                                pTypeV_Info_t->bCardNum++;
                            }
                            else
                            {
                                /* For all other error types, return error */
                                return status;
                            }
                            if(++bSlot == 16U)
                            {
                                bNextSlot = 0;
                            }

                            if(0U != (bNextSlot))
                            {
                                status = pcd_send_eof(aEofRecvTmpBuff, &bEofRecvTmpLen);
                            }
                        }
                        while(0U != bNextSlot);
                        bNextSlot = 1;

                        do
                        {
                            bRepeat = 0;
                            /* ?????????? */
                            if (0U != (wCollisionLogReg[bLevel]))
                            {
                                /* ???????????? */
                                for (bSlotCount = bCount[bLevel]; bSlotCount < 16U; bSlotCount++)
                                {
                                    /* ????????????????????????? */
                                    if (0U != (wCollisionLogReg[bLevel] & ((uint16_t)1U << bSlotCount)))
                                    {
                                        /* Increment the bit length by the 4 bits slot number */
                                        bMaskBitLength = bMaskBitLength + 4U;
                                        bit_index = mask_bit_number(bMaskBitLength);        //???bit
                                        byte_index = mask_byte_number(bMaskBitLength);      //??bit??pMask????

                                        (bit_index == BIT3) ? (last_bit = 0x0F) : (last_bit = 0xF0);      //??????????0-3??4-7

                                        (last_bit == 0x0F) ? (pMask[byte_index] = last_bit & bSlotCount) : (pMask[byte_index] |= (bSlotCount << 4));        //??pMask???

                                        pTypeV_Info_t->bCollPend = 1;
                                        wCollisionLogReg[bLevel] =  wCollisionLogReg[bLevel] & ~((uint16_t)1U  << bSlotCount);
                                        /* ?????? */
                                        if(bSlotCount == 0x0FU)
                                        {
                                            wCollisionLogReg[bLevel] = 0U;
                                            bCount[bLevel] = bSlotCount;
                                            bLevel++;
                                        }
                                        else
                                        {
                                            bCount[bLevel] = bSlotCount;
                                            bCount[bLevel]++;
                                            bLevel++;
                                        }
                                        break;
                                    }
                                    else
                                    {
                                        if(bSlotCount == 0x0FU)
                                        {
                                            if(bLevel == 0U)
                                            {
                                                bEnd = 1;
                                                pTypeV_Info_t->bCollPend = 0;
                                            }
                                            else
                                            {
                                                /* Decrement the bit length by the 4 bits slot number */
                                                pTypeV_Info_t->bCollPend = 0;
                                                bMaskBitLength = bMaskBitLength - 4u;
                                                wCollisionLogReg[bLevel] = 0;
                                                bCount[bLevel] = 0;
                                                bLevel--;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if(bLevel == 0U)
                                {
                                    pTypeV_Info_t->bCollPend = 0;
                                    bEnd = 1;
                                }
                                else
                                {
                                    /* Decrement the bit length by the 4 bits slot number */
                                    pTypeV_Info_t->bCollPend = 0;
                                    bMaskBitLength = bMaskBitLength - 4u;
                                    wCollisionLogReg[bLevel] = 0;
                                    bCount[bLevel] = 0;
                                    bLevel--;
                                    bRepeat = 1;
                                }
                            }
                        } while(0U != bRepeat);

                        if(0U == pTypeV_Info_t->bCollPend)
                        {
                            break;
                        }
                    } while(0U == bEnd);
                }
#if (USE_BIT_AND_SLOT_ANTI_COLLSION)
            }
#endif
            else
            {
                /* For all other error types, return error */
                return status;
            }
        }

#if (USE_BIT_AND_SLOT_ANTI_COLLSION)
    } while(status == MI_COLLERR);
#endif
    if(0U != (pTypeV_Info_t->bCardNum))
    {
        return HAL_STATUS_OK;
    }
    return status;
}

int pcd_stay_quiet(uint8_t *pUid, uint8_t bFlag)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("STAY_QUIET:\n");
    }

    pcd_set_15693_tmo(0);
    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = 10;
    pi.mf_data[0] = bFlag;	//Data_rate_flag | Address_flag;	//标志：单副载波、高速率、flag[8:5] 按照表5( 1 slot )
    pi.mf_data[1] = STAY_QUIET_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);

    status = pcd_com_transceive(&pi);

    if(status == HAL_STATUS_TIMEOUT)
    {
        return HAL_STATUS_OK;
    }

    return HAL_STATUS_PROTOCOL_ERR;

}

int pcd_reset_to_ready(uint8_t *pUid, uint8_t bFlag)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("RESET TO READY:\n");
    }

    pcd_set_15693_tmo(100);
    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = 10;
    pi.mf_data[0] = bFlag;	//Data_rate_flag | Address_flag;	//标志：单副载波、高速率、flag[8:5] 按照表5( 1 slot )
    pi.mf_data[1] = RESET_TO_READY_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);

    status = pcd_com_transceive(&pi);

    if(status == HAL_STATUS_TIMEOUT)
    {
        return HAL_STATUS_OK;
    }

    return HAL_STATUS_PROTOCOL_ERR;
}

int pcd_read_single_block(
    uint8_t  *pUid,
    uint8_t   bFlag,
    uint8_t   bBlockNum,
    uint8_t  *pRxBuffer,
    uint8_t  *pErr,
    uint16_t *pRxLength
)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("READ SINGLE BLOCK:\n");
    }

    pcd_set_15693_tmo(4);

    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = 11;
    pi.mf_data[0] = bFlag;//Data_rate_flag | Address_flag | Option_flag;	//标志：单副载波、高速率、flag[8:5] 按照表5( 1 slot )
    pi.mf_data[1] = READ_SINGLE_BLOCK_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);
    pi.mf_data[10] = bBlockNum;
    status = pcd_com_transceive(&pi);

    if (status != HAL_STATUS_OK)
    {
        return status;
    }

    if((pi.mf_length / 8 == 2) && (pi.mf_data[0] & ERROR_FLAG))
    {
        *pRxLength = 0;
        *pErr = pi.mf_data[1];
        return status;
    }
    else if(!(bFlag & OPTION_FLAG))
    {
        *pRxLength = (pi.mf_length / 8) - 1;
        memcpy(pRxBuffer, &pi.mf_data[1], *pRxLength);
    }
    else		//buffer第一个字节是安全状态
    {
        *pRxLength = (pi.mf_length / 8) - 1;
        memcpy(pRxBuffer, &pi.mf_data[1], *pRxLength);
    }

    return HAL_STATUS_OK;
}

int pcd_write_single_block(
    uint8_t  *pUid,
    uint8_t   bFlag,
    uint8_t   bBlockNum,
    uint8_t  *pTxBuffer,
    uint8_t  *pErr,
    uint16_t  wTxLength
)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("WRITE SINGLE BLOCK:\n");
    }

    pcd_set_15693_tmo(8);

    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = (11 + wTxLength);
    pi.mf_data[0] = bFlag;//Data_rate_flag | Address_flag | Option_flag;	//标志：单副载波、高速率、flag[8:5] 按照表5( 1 slot )
    pi.mf_data[1] = WRITE_SINGLE_BLOCK_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);
    pi.mf_data[10] = bBlockNum;
    memcpy(&pi.mf_data[11], pTxBuffer, wTxLength);

    status = pcd_com_transceive(&pi);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((pi.mf_length / 8 != 2) && (pi.mf_length / 8 != 1))
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    if((pi.mf_length / 8 == 2) && (pi.mf_data[0] & ERROR_FLAG))
    {
        *pErr = pi.mf_data[1];
    }

    return HAL_STATUS_OK;
}

int pcd_lock_block(uint8_t *pUid, uint8_t bFlag, uint8_t bBlockNum, uint8_t *pErr)

{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("LOCK BLOCK:\n");
    }

    pcd_set_15693_tmo(8);

    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = 11;
    pi.mf_data[0] = bFlag;
    pi.mf_data[1] = LOCK_BLOCK_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);
    pi.mf_data[10] = bBlockNum;
    status = pcd_com_transceive(&pi);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((pi.mf_length / 8 != 2) && (pi.mf_length / 8 != 1))
    {
        return PROTOCOL_ERR;
    }

    if((pi.mf_length / 8 == 2) && (pi.mf_data[0] & ERROR_FLAG))
    {
        *pErr = pi.mf_data[1];
    }

    return HAL_STATUS_OK;
}

int pcd_read_multiple_block(
    uint8_t  *pUid,
    uint8_t  bFlag,
    uint8_t  bBlockNum,
    uint8_t  bNumBlocks,
    uint8_t  *pRxBuffer,
    uint8_t  *pErr,
    uint16_t *pRxLength
)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("READ MULTIPLE BLOCK:\n");
    }

    pcd_set_15693_tmo(12);

    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = 12;
    pi.mf_data[0] = bFlag;
    pi.mf_data[1] = READ_MULTIPLE_BLOCK_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);
    pi.mf_data[10] = bBlockNum;
    pi.mf_data[11] = bNumBlocks;		//eg:bNumBlocks = 0x06其实是读7个块

    status = pcd_com_transceive(&pi);

    if (status != HAL_STATUS_OK)
    {
        return status;
    }

//	if((pi.mf_length / 8 != 2) 		//假设一个块是4个Byte
//		&& (pi.mf_length / 8 != (5 * (1 + bNumBlocks)))
//		&& (pi.mf_length / 8 != (4 * (1 + bNumBlocks))))
//	{
//		return HAL_STATUS_PROTOCOL_ERR;
//	}

    if((pi.mf_length / 8 == 2) && (pi.mf_data[0] & ERROR_FLAG))
    {
        *pErr = pi.mf_data[1];
    }
    else if((pi.mf_length / 8 != (4 * (1 + bNumBlocks))) && (!(bFlag & OPTION_FLAG)))
    {
        *pRxLength = (pi.mf_length / 8) - 1;
        memcpy(pRxBuffer, &pi.mf_data[1], *pRxLength);
    }
    else if((pi.mf_length / 8 != (5 * (1 + bNumBlocks))) && (!(bFlag & OPTION_FLAG)))
    {
        *pRxLength = (pi.mf_length / 8) - 1;
        memcpy(pRxBuffer, &pi.mf_data[1], *pRxLength);
    }
    else
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    return HAL_STATUS_OK;
}

int pcd_write_multiple_block(
    uint8_t  *pUid,
    uint8_t   bFlag,
    uint8_t   bBlockNum,
    uint8_t   bNumBlocks,
    uint8_t  *pTxBuffer,
    uint8_t  *pErr,
    uint16_t  wTxLength
)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("WRITE MULTIPLE BLOCK:\n");
    }

    pcd_set_15693_tmo(8);

    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = (12 + wTxLength);
    pi.mf_data[0] = bFlag;//Data_rate_flag | Address_flag | Option_flag;	//标志：单副载波、高速率、flag[8:5] 按照表5( 1 slot )
    pi.mf_data[1] = WRITE_MULTIPLE_BLOCK_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);
    pi.mf_data[10] = bBlockNum;
    pi.mf_data[11] = bNumBlocks;
    memcpy(&pi.mf_data[12], pTxBuffer, wTxLength);

    status = pcd_com_transceive(&pi);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((pi.mf_length / 8 != 2) && (pi.mf_length / 8 != 1))
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    if((pi.mf_length / 8 == 2) && (pi.mf_data[0] & ERROR_FLAG))
    {
        *pErr = pi.mf_data[1];
    }

    return HAL_STATUS_OK;
}

int pcd_select(uint8_t *pUid, uint8_t bFlag, uint8_t *pErr)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("SELECT:\n");
    }

    pcd_set_15693_tmo(3);

    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = 10;
    pi.mf_data[0] = bFlag;	//标志：单副载波、高速率、flag[8:5] 按照表5( 1 slot )
    pi.mf_data[1] = SELECT_CMD;	//cmd：	查找所以处于RF场内的VICC
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);

    status = pcd_com_transceive(&pi);
    if(status != HAL_STATUS_OK)
    {
        return status;
    }

    if((pi.mf_length / 8 != 2) && (pi.mf_length / 8 != 1))
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    if((pi.mf_length / 8 == 2) && (pi.mf_data[0] & ERROR_FLAG))
    {
        *pErr = pi.mf_data[1];
    }

    return HAL_STATUS_OK;
}

int pcd_write_afi(uint8_t *pUid, uint8_t bFlag, uint8_t bAfi, uint8_t *pErr)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  pi;

    if(NFC_DEBUG_LOG)
    {
        printf("WRITE AFI:\n");
    }

    pcd_set_15693_tmo(8);

    pi.mf_command = PCD_TRANSCEIVE;
    pi.mf_length = 11;
    pi.mf_data[0] = bFlag;
    pi.mf_data[1] = WRITE_AFI_CMD;
    memcpy(&pi.mf_data[2], pUid, ISO15693_UID_LENGTH);
    pi.mf_data[10] = bAfi;
    status = pcd_com_transceive(&pi);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((pi.mf_length / 8 != 2) && (pi.mf_length / 8 != 1))
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    if((pi.mf_length / 8 == 2) && (pi.mf_data[0] & ERROR_FLAG))
    {
        *pErr = pi.mf_data[1];
    }

    return HAL_STATUS_OK;

}

int pcd_lock_afi(uint8_t *pUid, uint8_t bFlag, uint8_t *pErr)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  mf_com_data;

    if(NFC_DEBUG_LOG)
    {
        printf("LOCK BLOCK:\n");
    }

    pcd_set_15693_tmo(8);

    mf_com_data.mf_command = PCD_TRANSCEIVE;
    mf_com_data.mf_length = 10;
    mf_com_data.mf_data[0] = bFlag;
    mf_com_data.mf_data[1] = LOCK_AFI_CMD;
    memcpy(&mf_com_data.mf_data[2], pUid, ISO15693_UID_LENGTH);
    status = pcd_com_transceive(&mf_com_data);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((mf_com_data.mf_length / 8 != 2) && (mf_com_data.mf_length / 8 != 1))
    {
        return PROTOCOL_ERR;
    }

    if((mf_com_data.mf_length / 8 == 2) && (mf_com_data.mf_data[0] & ERROR_FLAG))
    {
        *pErr = mf_com_data.mf_data[1];
    }

    return HAL_STATUS_OK;
}

int pcd_write_dsfid(uint8_t *pUid, uint8_t bFlag, uint8_t bDsfid, uint8_t *pErr)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  mf_com_data;

    if(NFC_DEBUG_LOG)
    {
        printf("WRITE AFI:\n");
    }

    pcd_set_15693_tmo(8);

    mf_com_data.mf_command = PCD_TRANSCEIVE;
    mf_com_data.mf_length = 11;
    mf_com_data.mf_data[0] = bFlag;
    mf_com_data.mf_data[1] = WRITE_DSFID_CMD;
    memcpy(&mf_com_data.mf_data[2], pUid, ISO15693_UID_LENGTH);
    mf_com_data.mf_data[10] = bDsfid;
    status = pcd_com_transceive(&mf_com_data);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((mf_com_data.mf_length / 8 != 2) && (mf_com_data.mf_length / 8 != 1))
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    if((mf_com_data.mf_length / 8 == 2) && (mf_com_data.mf_data[0] & ERROR_FLAG))
    {
        *pErr = mf_com_data.mf_data[1];
    }

    return HAL_STATUS_OK;
}


int pcd_lock_dsfid(uint8_t *pUid, uint8_t bFlag, uint8_t *pErr)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  mf_com_data;

    if(NFC_DEBUG_LOG)
    {
        printf("LOCK BLOCK:\n");
    }

    pcd_set_15693_tmo(8);

    mf_com_data.mf_command = PCD_TRANSCEIVE;
    mf_com_data.mf_length = 10;
    mf_com_data.mf_data[0] = bFlag;
    mf_com_data.mf_data[1] = LOCK_DSFID_CMD;
    memcpy(&mf_com_data.mf_data[2], pUid, ISO15693_UID_LENGTH);
    status = pcd_com_transceive(&mf_com_data);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((mf_com_data.mf_length / 8 != 2) && (mf_com_data.mf_length / 8 != 1))
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    if((mf_com_data.mf_length / 8 == 2) && (mf_com_data.mf_data[0] & ERROR_FLAG))
    {
        *pErr = mf_com_data.mf_data[1];
    }

    return HAL_STATUS_OK;
}

int pcd_get_system_information(
    uint8_t  *pUid,
    uint8_t   bFlag,
    uint8_t  *pErr,
    uint8_t  *pRxBuffer,
    uint16_t *pRxLength
)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  mf_com_data;

    if(NFC_DEBUG_LOG)
    {
        printf("GET SYSTEM INFORMATION:\n");
    }

    pcd_set_15693_tmo(8);

    mf_com_data.mf_command = PCD_TRANSCEIVE;
    mf_com_data.mf_length = 10;
    mf_com_data.mf_data[0] = bFlag;//Data_rate_flag | Address_flag;	//标志：单副载波、高速率、flag[8:5] 按照表5( 1 slot )
    mf_com_data.mf_data[1] = GET_SYSTEM_INFORMATION_CMD;	//cmd：	查找所以处于RF场内的VICC
    memcpy(&mf_com_data.mf_data[2], pUid, ISO15693_UID_LENGTH);

    status = pcd_com_transceive(&mf_com_data);

    if (status != HAL_STATUS_OK)
    {
        return status;
    }

    if((mf_com_data.mf_length / 8 == 2) && (mf_com_data.mf_data[0] & ERROR_FLAG))
    {
        *pRxLength = 0;
        *pErr = mf_com_data.mf_data[1];
        return status;

    }
    *pRxLength = (mf_com_data.mf_length / 8);
    memcpy(pRxBuffer, &mf_com_data.mf_data[0], *pRxLength);

    return HAL_STATUS_OK;
}

int pcd_get_multiple_block_security_status(
    uint8_t  *pUid,
    uint8_t   bFlag,
    uint8_t   bBlockNum,
    uint8_t   bNumBlocks,
    uint8_t  *pErr,
    uint8_t  *pSecurityStatus,
    uint16_t *pSecStaLength
)
{
    int  status = HAL_STATUS_OK;
    hal_nfc_transceive_t  mf_com_data;

    printf("GET MULTTIPLE BLOCK SECURITY STATUS:\n");
    pcd_set_15693_tmo(8);

    mf_com_data.mf_command = PCD_TRANSCEIVE;
    mf_com_data.mf_length = 12;
    mf_com_data.mf_data[0] = bFlag;
    mf_com_data.mf_data[1] = GET_MULTTIPLE_BLOCK_SECURITY_STATUS_CMD;
    memcpy(&mf_com_data.mf_data[2], pUid, ISO15693_UID_LENGTH);
    mf_com_data.mf_data[10] = bBlockNum;
    mf_com_data.mf_data[11] = bNumBlocks;

    status = pcd_com_transceive(&mf_com_data);

    if (status != HAL_STATUS_OK)		//return以后根据option_flag决定是否要发送EOF从而接收数据
    {
        return status;
    }

    if((mf_com_data.mf_length / 8 != 2) && (mf_com_data.mf_length / 8 != (bNumBlocks + 1)))
    {
        return HAL_STATUS_PROTOCOL_ERR;
    }

    if((mf_com_data.mf_length / 8 == 2) && (mf_com_data.mf_data[0] & ERROR_FLAG))
    {
        *pErr = mf_com_data.mf_data[1];
    }

    *pSecStaLength = (mf_com_data.mf_length / 8) - 1;
    memcpy(pSecurityStatus, &mf_com_data.mf_data[1], *pSecStaLength);

    return HAL_STATUS_OK;
}

void pcd_set_15693_tmo(uint8_t time)
{
    hal_nfc_write_register(REG_TPRESCALER, (2048) & 0xFF);
    hal_nfc_write_register(REG_TMODE, BIT(7) | (((2048)>>8) & 0xFF));

    hal_nfc_write_register(REG_TRELOADL, (1 << time) & 0xFF);
    hal_nfc_write_register(REG_TRELOADH, ((1 << time) & 0xFF00) >> 8);
}



int com_write_read_blocks_and_check(
   uint8_t  *pUid,     
   uint8_t   bFlag,
   uint8_t   bBlockNum,
   uint8_t   bNumBlocks,
   uint8_t  *pErr,
   uint8_t  *pRxBuffer,
   uint8_t  *pTxBuffer,
   uint16_t *pRxLength,
   uint16_t *pTxLength
)
{
  uint16_t i            = 0;
	int status           = HAL_STATUS_OK;
  uint8_t flag         = 0x02;
  printf("WRITE/READ BLOCKS AND CHECK \n");
  

  
  for(i = 0;i < *pTxLength;i+=4)
  {
    status = pcd_write_single_block(pUid, bFlag, bBlockNum+(i/4), pTxBuffer+i, pErr, 4);
    
    if(status == HAL_STATUS_OK)
    {
      if(*pErr != 0)
      {
        return -1;
      }
    }
    else if((flag & OPTION_FLAG) && (status == HAL_STATUS_TIMEOUT))
    {
      status = pcd_send_eof(pRxBuffer, pRxLength);
    }
    else 
    {//status illegal
      g_statistics.inv_fail++;       
    }
  }
  status = pcd_read_multiple_block(pUid,bFlag,bBlockNum,bNumBlocks,pRxBuffer,pErr,pRxLength);
  if(status == HAL_STATUS_OK)
  {
    if(*pErr != 0)
    {
      return -2;
    }
    if(memcmp(pRxBuffer, pTxBuffer,*pRxLength))
    {
      return -3;
    }
  }
    else
    {//status illegal
      g_statistics.inv_fail++;
    }
  
  return 0;
}

